home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
003
/
soundex.prg
< prev
next >
Wrap
Text File
|
1987-02-22
|
7KB
|
182 lines
* Purpose of this program:
* 1. Store the soundex code for every entry in a database file with a
* character field containing the last name.
* 2. Enter a last name. This program generates a soundex code for it,
* and retrieves all records matching the code.
* (The codes are case insensitive)
*
* Original program from the Data Based Advisor, Aug., 1984 page 46
* By John Gillen, Lexicon Publishing, 725 J Street,
* Sacramento, CA 95814
*
* Adapted to Dbase III and modified June 14, 1985 by
* Michael Shunfenthal,
* 2602 West 235 Street, Torrance CA 90505
*
* To use this program:
* 1. Modify the structure of your database to add a 4-character field
* to hold the soundex code for each last name. Then enter:
* set procedure to soundex
*
* 2. Set the code into this field for the entire database:
* (the program requires approximately 8 seconds for each record)
* do sndxrpl with '<dbfname>', '<soundex field>', '<lastname field>'
*
* 3. Retrieve records having the same code for the entered last name:
* do sndxdisp with '<dbfname>', '<soundex field>', '<last name>'
*
* Notes on above commands:
* 1. The apostrophes (or double quotes, or brackets) are required
* per the DbaseIII manual, do delimit character values.
* 2. Omit the angle brackets: <>.
* 3. The last name field or entry may have an embedded apostrophe
* ("O'Brian"), space, or hyphen.
*
*************************************************************************
* Program operation: (procedure sndxcalc)
* Create a Soundex code for the last name parameter
* (either a field or variable) and save in public variable msndx1
* 1. Assign a value to the first letter. This value differs from the
* classical soundex value, as it is a number. The same value is
* assigned to several letters; see below and the article.
* 2. Check for and remove double consonants
* 3. Assign a value to the remaining letters
* 4. Adjust the code length to four characters
* 5. Store this value in the soundex field
*
* Modifications to the original article listing:
* 1. Added multiple functions:
* a. Store the soundex code for a given last name field (input)
* and a given soundex-code field (output) in a given database
* b. Retrieve names given a last name, last-name field,
* and soundex field
* 2. Made more generalized: replaced the hard coded database file name
* and field names with user-entered parameters
* 3. Fix bugs: ignore an apostrophe, hyphen, and space within the last name.
*
procedure sndxrpl
parameter dbfname, lastnmfld, sndxfld
public msndx1
set talk off
use &dbfname
do while .not. eof()
mlastnm = &lastnmfld
do sndxcalc with "&mlastnm"
? ' The record number: ' + str(recno(),4)
?? ' Last name: ' + &lastnmfld + ' Soundex code: ' + msndx1
replace &sndxfld with msndx1
skip
enddo
set talk on
clear
return
procedure sndxdisp
parameter dbfname, sndxfld, lastnam
public msndx1
set talk off
use &dbfname
do sndxcalc with "&lastnam"
? ' The soundex code for the given last name: ' + msndx1
display all off for &sndxfld='&msndx1'
set talk on
return
procedure sndxcalc
parameter charname
store upper(trim("&charname")) to mtr
store substr(mtr,1,1) to m1
store len(mtr) to length
store substr(mtr,2,length) to m2
* assign a value to the first letter
do case
case m1='A' .or. m1='E' .or. m1='H' .or. m1='I' .or. m1='O' .or. ;
m1='U' .or. m1='W' .or. m1='Y'
store '0' to msndx1
case m1='B' .or. m1='F' .or. m1='P' .or. m1='V'
store '1' to msndx1
case m1='C' .or. m1='G' .or. m1='J' .or. m1='K' .or. m1='Q' .or. ;
m1='S' .or. m1='X' .or.m1='Z'
store '2' to msndx1
case m1='D' .or. m1='T'
store '3' to msndx1
case m1='L'
store '4' to msndx1
case m1='M' .or. m1='N'
store '5' to msndx1
case m1='R'
store '6' to msndx1
endcase
store 1 to pos
* check for and ignore double consonants
do while pos < length-1
store substr(m2,pos,1) to mck1
store substr(m2,pos+1,1) to mck2
if mck1=mck2
store at('&mck2',m2) to mleft
store substr(m2,1,mleft) to mlend
store substr(m2,mleft+2,length) to mrtend
store mlend - mrtend to m2
store len(m2) to length
endif
store pos+1 to pos
enddo
store 1 to pos
store ' ' to msndx2
store 0 to mcklen
store len(m2) to length
* assign values remaining characters, dropping vowels and h, w
do while pos<=length .and. length>1 .and. mcklen<4
store substr(m2,pos,1) to m3
do case
* remove vowels and an apostrophe
case m3='A' .or. m3='E' .or. m3='H' .or. m3='I' .or. m3='O' .or. ;
m3='U' .or. m3='W' .or. m3='Y' .or. m3="'" .or. m3=' ' .or. m3='-'
do case
* if found in the first character, keep the remainder
case pos=1
store length-1 to newlen
store substr(m2,2,newlen) to m2
store len(m2) to length
* if found in the middle save each side
case pos>1 .and. pos<length
store at('&m3',m2) to mleft
store substr(m2,1,mleft-1) to mlfend
store length-pos to newlen
store substr(m2,mleft+1,newlen) to mrtend
store mlfend-mrtend to m2
store len(m2) to length
* if found at right end, save to next-to-last char
case pos=length
store substr(m2,1,length-1) to m2
store len(m2) to length
endcase
* append remaining letter values to first
case m3='B' .or. m3='F' .or. m3='P' .or. m3='V'
store msndx1-'1' to msndx1
store pos+1 to pos
case m3='C' .or. m3='G' .or. m3='J' .or. m3='K' .or. m3='Q' .or. ;
m3='S' .or. m3='X' .or.m3='Z'
store msndx1-'2' to msndx1
store pos+1 to pos
case m3='D' .or. m3='T'
store msndx1-'3' to msndx1
store pos+1 to pos
case m3='L'
store msndx1-'4' to msndx1
store pos+1 to pos
case m3='M' .or. m3='N'
store msndx1-'5' to msndx1
store pos+1 to pos
case m3='R'
store msndx1-'6' to msndx1
store pos+1 to pos
endcase
* check for soundex length less than 4 chars
store len(msndx1) to mcklen
enddo while
do while mcklen<4
store msndx1-'0' to msndx1
store len(msndx1) to mcklen
enddo
return